#!/usr/bin/env python3
"""
- Why working with the root logger for all modules isn’t the best idea?
The default logger is called root.
Once configured, the root logger in the main file (that imported the ‘myprojectmodule‘ module) will no longer be able to change the root logger settings.
Because, the logging.basicConfig() once set cannot be changed.
if you want to log the messages from myprojectmodule to one file and the logs from the main module in another file, root logger can’t that.
The printed log message has the following default format: {LEVEL}:{LOGGER}:{MESSAGE}.

- To do that you need to create a new logger.
You can create a new logger using the ‘logger.getlogger.info(__name__)‘ method.
Notice how we set the formatter on the ‘file_handler‘ and not the ‘logger‘ directly.
Besides ‘debug‘, ‘info‘, ‘warning‘, ‘error‘, and ‘critical‘ messages, you can log exceptions that will include any associated traceback information.
logger.exception will log the message provided in its arguments as well as the error message traceback info.

- Another aspect to note is, all the loggers have a built-in hierarchy to it.
if you have configured the root logger to log messages to a particular file.
You also have a custom logger for which you have not configured the file handler to send messages to console or another log file.
In this case, the custom logger will fallback and write to the file set by the root logger itself.
Until and unless you configure the log file of your custom logger.

you call logging.{level}(message) to show the message in console.

You can configure a logger that prints to the console and another logger that sends the logs to a file,
has a different logging level and is specific to a given module. More explanations and examples coming up on this.

[Attribute name]    Format    Description
logging — Logging facility for Python — Python 3.9.6 documentation
https://docs.python.org/3/library/logging.html

10+ practical examples to use python logging() in detail | GoLinuxCloud
https://www.golinuxcloud.com/python-logging/#Configure_logging_using_dictConfig

Python Logging - Simplest Guide with Full Code and Examples | ML+
https://www.machinelearningplus.com/python/python-logging-guide/
"""
import os
import sys
import logging
from logging.handlers import RotatingFileHandler


if not os.path.exists('logs'):
    os.mkdir('logs')

# Log file location
log_name = __name__.split('.')[0]
logfile = os.path.join('logs', log_name + '.log')

# Gets or creates a logger
# Define your own logger name
logger = logging.getLogger(log_name + "_logger")
# Set default logging level to DEBUG
logger.setLevel(logging.DEBUG)

# create a console handler
# and define a custom log format, set its log level to DEBUG
print_format = logging.Formatter('%(levelname)-8s %(name)-12s %(message)s')
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(print_format)

# create a log file handler
# and define a custom log file format, set its log level to DEBUG

# log_format = logging.Formatter('[%(asctime)s] %(levelname)-8s %(name)-12s %(message)s')
# file_handler = logging.FileHandler(filename=logfile)
# file_handler.setLevel(logging.DEBUG)
# file_handler.setFormatter(log_format)

# create a rotating log file handler
# and define a custom log file format, set its log file level to DEBUG
# the full log file is 10KB, a number of backup is 3 log files
# Don't use two file handler to open the same log file in one py file. otherwise, the second will throw a permission error, when rename the log file
rotating_log_format = logging.Formatter(
    '[%(asctime)s] %(levelname)-8s %(name)-12s %(message)s [in %(pathname)s:%(lineno)d]')
rotating_file_handler = RotatingFileHandler(
    filename=logfile, maxBytes=10240, backupCount=3)
rotating_file_handler.setLevel(logging.DEBUG)
rotating_file_handler.setFormatter(rotating_log_format)

# Add fille handlers to the logger
logger.addHandler(rotating_file_handler)
logger.addHandler(console_handler)

# Write messages with all different types of levels
# logger.debug('debug')
# logger.info('info')
# logger.warning('warning')
# logger.error('error')
# logger.critical('critical')

# Execute the script, the output on the console contains all message levels above DEBUG in the hierarchy using our defined log format
# CRITICAL logger_logger    critical
# DEBUG    logger_logger    debug
# INFO     logger_logger    info
# WARNING  logger_logger    warning
# ERROR    logger_logger    error
# CRITICAL logger_logger    critical

# while the log file logger.log contains all message levels above DEBUG in the hierarchy using our defined log format
# [2020-06-24 19:50:00,433] DEBUG    logger_logger    debug
# [2020-06-24 19:50:00,433] INFO     logger_logger    info
# [2020-06-24 19:50:00,434] WARNING  logger_logger    warning
# [2020-06-24 19:50:00,434] ERROR    logger_logger    error
# [2020-06-24 19:50:00,434] CRITICAL logger_logger    critical


# def divide(x, y):
# try:
# out = x / y
# except ZeroDivisionError:
# logger.exception("Division by zero problem")
# else:
# return out

# Logs  output on console
# logger.error("Divide {x} / {y} = {c}".format(x=10, y=0, c=divide(10,0)))

# ERROR    app_logger   Division by zero problem
# Traceback (most recent call last):
# File "d:\E000...\app\logger.py", line 45, in divide
# out = x / y
# ZeroDivisionError: division by zero
# ERROR    app_logger   Divide 10 / 0 = None
